#include"jiajia_lmcc.h"

static JiaJia_file_pool_t _jjfpool = {NULL};

static void _JiaJia_file_free_word(JiaJia_file_pt jjfile){
    JiaJia_word_t *del = NULL;
    while((del = jjfile->word_begin) != NULL){
        jjfile->word_begin = del->next;
        del->next = NULL;
        Yu_free(del);
    }

    _JiaJia_file_wordinit(jjfile);
}

static void _JiaJia_file_meminit(void *pt, size_t size){
    JiaJia_file_pt jjfile = (JiaJia_file_pt)pt;

    jjfile->state = _JiaJia_FILE_CLOSE;
    jjfile->stream = NULL;

    /* 初始化 word 相关 */
    jjfile->word_begin = NULL;
    jjfile->word_end = NULL;
    jjfile->word_next = NULL;

    /* 初始化 item 相关 */
    jjfile->item_reduce = NULL;

    /* parse data 相关 */
    jjfile->pdata_top = NULL;

    jjfile->last_file = NULL;
}

/* 加加文件的内存管理器释放函数。 */
static void _JiaJia_file_memfree(void *pt, size_t size){
    JiaJia_file_pt jjfile = (JiaJia_file_pt)pt;

    /* 释放文件名字。 */
    if(jjfile->fname != NULL)
        Yu_free(jjfile->fname);

    /* 释放加加流 */
    if(jjfile->stream != NULL)
        Yu_free(jjfile->stream);

    /* 重新初始化 */
    _JiaJia_file_meminit(pt, size);
}

extern JiaJia_file_pt JiaJia_file_top(){
    return _jjfpool.last_file;
}

/* 加加文件的打开操作。 */
extern JiaJia_file_pt JiaJia_file_open(const char *filename){
    JiaJia_stream_pt stream = Yu_alloc(sizeof(JiaJia_stream), JiaJia_stream_meminit, JiaJia_stream_memfree);
    
    int32_t ret = JiaJia_stream_open(stream, filename);

    switch(ret){
    case JIAJIA_STREAM_OPEN_FAIL:
    case JIAJIA_STREAM_OPEN_NOEXIT:
    case JIAJIA_STREAM_OPEN_NOTYPE:
        Yu_exit(0, "无法打开加加文件 %s\n", filename);
        break;
    }

    /* 初始化文件内容 */
    JiaJia_file_pt jjfile = Yu_alloc(sizeof(JiaJia_file_t), _JiaJia_file_meminit, _JiaJia_file_memfree);

    jjfile->fname = Yu_u8_alloc(filename);
    jjfile->stream = stream;


    jjfile->last_file = _jjfpool.last_file;
    _jjfpool.last_file = jjfile;

    return 0;
}

extern void JiaJia_file_close(){
    JiaJia_file_pt del = _jjfpool.last_file;

    if(del == NULL) return;

    _jjfpool.last_file = del->last_file;
    del->last_file = NULL;

    Yu_free(del);
}

extern JiaJiaLmcc_pdata_pt JiaJia_file_push_pdata(){
    JiaJia_file_pt jjfile = JiaJia_file_top();
    JiaJiaLmcc_pdata_pt ret = JiaJiaLmcc_pdata_alloc();

    if(jjfile->pdata_top != NULL)
        ret->next = jjfile->pdata_top;
    jjfile->pdata_top = ret;

    return ret;
}

extern void JiaJia_file_pop_pdata(){
    JiaJia_file_pt jjfile = JiaJia_file_top();
    JiaJiaLmcc_pdata_pt del = jjfile->pdata_top;

    if(del == NULL) return;

    jjfile->pdata_top = del->next;
    del->next = NULL;

    Yu_free(del);
}
